﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DecisionMaking.BusinessLogic;
using DecisionMaking.BusinessLogic.Model;
using DecisionMaking.Domain.Reports;
using DecisionMaking.WebApp.Charts;

namespace DecisionMaking.WebApp.Controllers
{
    [HandleError]
    [Authorize]
    public class ReportsController : BaseController
    {
        public IReportManager ReportManager {private get; set;} // injected by Windsor
        public IAlgorithmManager AlgorithmManager {private get; set; } // injected by Windsor
        public IEnvironmentManager EnvironmentManager {private get; set; } // injected by Windsor
        public IExecutionManager ExecutionManager {private get; set; } // injected by Windsor

        [HttpGet]
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        public ActionResult AverageProportionOfCorrectInferences(ReportModel model)
        {
            PopulateModel(model);

            if (model.Execute)
            {
                ViewData["report"] = ReportManager.GetAverageProportionOfCorrectInferences(model);                
            }

            return View(model);
        }

        public ActionResult SingleAlgorithmPerformance(ReportModel model)
        {
            PopulateModel(model);

            if (model.Execute)
            {
                var report = ReportManager.GetSingleAlgorithmPerformance(model);
                int[] sets = { 0, 10, 20, 50, 75, 100 };


                if (report.Count > 0)
                {
                    ViewData["categories"] = (from e in report 
                                              orderby e.NumOfObjectsRecognized 
                                              group e by e.NumOfObjectsRecognized into g  
                                              select g.Key).ToArray();
                    ViewData["xAxisName"] = "Number of Objects Recognized";
                    ViewData["yAxisName"] = "% Correct Inferences";

                    // data set for each pct of cue values known value, where 
                    ViewData["dataSets"] = (from s in sets
                                    select new DataSet<double>
                                    {
                                        Name = s + "",
                                        Data = (from e in report
                                                where e.PctOfCueValuesKnown == s
                                                orderby e.NumOfObjectsRecognized
                                                group e by e.NumOfObjectsRecognized
                                                into g
                                                select g.Average(p => p.AvgCorrectInferences))

                                    }).ToList();
                    
                    ViewData["report"] = report;

                }
            }

            return View(model);            
        }

        public ActionResult AlgorithmPerformanceComparison(ReportModel model)
        {
            PopulateModel(model);

            if (model.Execute)
            {
                var report = ReportManager.GetAllAlgorithmsPerformance(model);

                if (report.Count > 0)
                {
                    var sets = (from e in report group e by e.Algorithm into g select g.Key);

                    ViewData["categories"] = (from e in report
                                              orderby e.NumOfObjectsRecognized
                                              group e by e.NumOfObjectsRecognized into g
                                              select g.Key).ToArray();
                    ViewData["xAxisName"] = "Number of Objects Recognized";
                    ViewData["yAxisName"] = "% Correct Inferences";

                    // data set for each pct of cue values known value, where 
                    ViewData["dataSets"] = (from s in sets
                                            select new DataSet<double>
                                            {
                                                Name = s,
                                                Data = (from e in report
                                                        where e.Algorithm == s
                                                        orderby e.NumOfObjectsRecognized
                                                        group e by e.NumOfObjectsRecognized
                                                            into g
                                                            select g.Average(p => p.AvgCorrectInferences))

                                            }).ToList();

                    ViewData["report"] = report;

                }
            }

            return View(model);
        }

        private void PopulateModel(ReportModel model)
        {
            model.AlgorithmDefinitions = AlgorithmManager.GetAlgorithmDefinitions(CurrentAccount.Id);
            model.Environments = EnvironmentManager.GetPublicAndUsersEnvironments(CurrentAccount.Id);
            model.Simulations = ExecutionManager.GetSimulationOutcomes(CurrentAccount.Id);
        }

    }
}
